﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using DB;
using PerceptiveMCAPI;
using PerceptiveMCAPI.Methods;
using PerceptiveMCAPI.Types;

namespace API
{
    public class MailChimpApi
    {
        private MailChimpApi _api;

        private readonly string _apikey;
        private MailChimpApi(string strApiKey)
        {
            _apikey = strApiKey;// "3d6d789a0e724944efb72179d077f32c-us7";
        }

        static readonly Dictionary<string,MailChimpApi> DicApis = new Dictionary<string, MailChimpApi>();
        public static MailChimpApi GetApi(string strApiKey)
        {
            if (!DicApis.ContainsKey(strApiKey))
            {
                DicApis.Add(strApiKey,new MailChimpApi(strApiKey));
            }
            return DicApis[strApiKey];
        }

        public bool GetCampaignsData(Dictionary<string,object> filer,int page,out List<campaignsResults.DataItem> dataList,out int total)
        {
           /* Dictionary<string,object> filer = new Dictionary<string, object>();
            filer.Add("sendtime_start", "2012-01-01 00:00:00");
            filer.Add("status", "sent");*/
            dataList = new List<campaignsResults.DataItem>();
            total = 0;
            campaignsInput input = new campaignsInput(_apikey, filer, page, 1000);
            campaigns camp = new campaigns(input);
            campaignsOutput output = camp.Execute();
            dataList = output.result.data;
            total = output.result.total;
            return output.api_ErrorMessages.Count == 0;
        }

        public bool UnSubScriptEmailList(string cid, out List<campaignUnsubscribesResults.Unsubscribes> dataList)
        {
            dataList = new List<campaignUnsubscribesResults.Unsubscribes>();
           // total = 0;
            campaignUnsubscribesInput input = new campaignUnsubscribesInput(_apikey, cid);
            campaignUnsubscribes unsupscript = new campaignUnsubscribes(input);
            campaignUnsubscribesOutput output = unsupscript.Execute();
            campaignUnsubscribesResults result = output.result;
            dataList = result.data;
          //  total = result.total;
            return output.api_ErrorMessages.Count == 0;
        }

        //获取邮件list
        public bool GetLists(out Dictionary<string, string> dicEmailList)
        {
            try
            {
                dicEmailList = new Dictionary<string, string>();
                var input = new listsInput(_apikey);
           
                var cmd = new lists(input);
                listsOutput output = cmd.Execute();
                listsResults result = output.result;
          
                foreach (var value in result.data)
                {
                    dicEmailList.Add(value.id, value.name);
                }
                return output.api_ErrorMessages.Count == 0;
            }
            catch (Exception ex)
            {
                dicEmailList = null;
                Trace.WriteLine("GetEmailList " + ex.ToString());
                return false;
            }
        }

        //获取邮件list
        public bool GetEmailList(string listId)
        {
            listMembersInput Input = new listMembersInput(this._apikey,listId,EnumValues.listMembers_status.unsubscribed);
            var cmd = new listMembers(Input);
            listMembersOutput Output;
            Output = cmd.Execute();
            List<string> list = new List<string>();
            List<string> listtext = new List<string>();
            foreach (var listAbuseReportsResult in Output.result.data)
            {
                if(!list.Contains(listAbuseReportsResult.reason))
                {
                    list.Add(listAbuseReportsResult.reason);
                }
                if (!listtext.Contains(listAbuseReportsResult.reason_text))
                {
                    listtext.Add(listAbuseReportsResult.reason_text);
                }
            }
            return true;
        }

        public bool SaveAbuseEmailToDb(string listId)
        {
            listMembersInput Input = new listMembersInput(this._apikey, listId, EnumValues.listMembers_status.unsubscribed, 0, 10000);
            var cmd = new listMembers(Input);
            listMembersOutput Output;
            Output = cmd.Execute();
            foreach (var listAbuseReportsResult in Output.result.data)
            {
                if (listAbuseReportsResult.reason != "")
                {
                    EmailsDb.DbMysql.UpdateMailChimpEmailStatus(listAbuseReportsResult.email,
                                                                listAbuseReportsResult.reason);
                }
            }
            return true;
            
        }


        //获取邮件list
        public bool GetAbuseEmailList(string listId)
        {
            listAbuseReportsInput Input = new listAbuseReportsInput(this._apikey, listId, DateTime.Now.AddDays(-20));
            var cmd = new listAbuseReports(Input);
            listAbuseReportsOutput Output;
            Output = cmd.Execute();
            foreach (var abuse in Output.result.data)
            {
                
            }
            return true;
        }
        #region 订阅 退订
        //将邮件加入到list中
        public bool BatchSubscribeToList(string listId, List<EmailInfo> subscribeEmailList)
        {
            Debug.WriteLine("BatchSubscribeToList");
            var batch = new List<Dictionary<string, object>>();
            int i = 0;
            foreach (var list in subscribeEmailList)
            {
                var entry = new Dictionary<string, object>();
                entry.Add("EMAIL", list.Email);
                entry.Add("FNAME", list.Name);
                batch.Add(entry);
                i++;

                if (i == 2000)
                {
                    if (!BatchSubscribe(listId, batch)) return false;
                    batch = new List<Dictionary<string, object>>();
                    i = 0;
                }
            }

            if (batch.Count >0)
            {
                if (!BatchSubscribe(listId, batch)) return false;
            }
            return true;
        }

        private bool BatchSubscribe(string listId, List<Dictionary<string, object>> batch)
        {
            Debug.WriteLine("BatchSubscribe Beg");
            var inPut = new listBatchSubscribeInput(_apikey, listId, batch, false, true, true);
            var batchSubscribe = new listBatchSubscribe(inPut);
            listBatchSubscribeOutput outPut = batchSubscribe.Execute();
            listBatchSubscribeResults result = outPut.result;
            Debug.WriteLine("count: " + batch.Count);

            if (outPut.api_ErrorMessages.Count > 0)
            {
                Debug.WriteLine(outPut.api_ErrorMessages);
                return false;
            }
            Debug.WriteLine("BatchSubscribe Success");
            return true;
        }


        public bool BatchUnSubscribeToList(string listId, List<string> listEmail)
        {
            Debug.WriteLine("BatchUnSubscribeToList");
            var batch = new List<string>();
            int i = 0;
            foreach (var list in listEmail)
            {
                batch.Add(list);
                i++;

                if (i == 2000)
                {
                    if (!BatchUnSubscribe(listId, batch)) return false;
                    batch = new List<string>() ;
                    i = 0;
                }
            }

            if (batch.Count > 0)
            {
                if (!BatchUnSubscribe(listId, batch)) return false;
            }
            return true;
        }

        public bool BatchUnSubscribeList(string listId)
        {
            listMembersInput Input = new listMembersInput(this._apikey, listId, EnumValues.listMembers_status.subscribed,0,5000);
            var cmd = new listMembers(Input);
            listMembersOutput Output;
            Output = cmd.Execute();
            List<string> listEmail = new List<string>();
            foreach (var listAbuseReportsResult in Output.result.data)
            {
                if (!listEmail.Contains(listAbuseReportsResult.email))
                {
                    listEmail.Add(listAbuseReportsResult.email);
                }
            }
            Debug.WriteLine("BatchUnSubscribeToList");
            var batch = new List<string>();
            int i = 0;
            foreach (var list in listEmail)
            {
                batch.Add(list);
                i++;

                if (i == 2000)
                {
                    if (!BatchUnSubscribe(listId, batch)) return false;
                    batch = new List<string>();
                    i = 0;
                }
            }

            if (batch.Count > 0)
            {
                if (!BatchUnSubscribe(listId, batch)) return false;
            }
            return true;
        }

        public bool BatchUnSubscribe(string listId, List<string> listEmail)
        {
            Debug.WriteLine("BatchUnSubscribe Beg");
            var input = new listBatchUnsubscribeInput(_apikey, listId, listEmail);
            var unsubscribe = new listBatchUnsubscribe(input);
            var output = unsubscribe.Execute();
            var result = output.result;
            Debug.WriteLine("count: " + listEmail.Count);

            if (output.api_ErrorMessages.Count > 0)
            {
                Debug.WriteLine(output.api_ErrorMessages);
                return false;
            }
            Debug.WriteLine("BatchUnSubscribe Success");
            return true;
        }
        #endregion

        public bool GetTemplatesList(out Dictionary<double, string> dicTemplates)
        {
            dicTemplates = new Dictionary<double, string>();
            templatesParms.return_types type = new templatesParms.return_types();
            templatesParms.return_inactives inactives = new templatesParms.return_inactives();
            templatesInput templatesInput = new templatesInput(_apikey, type, "", inactives);
            templates templates = new templates(templatesInput);
            templatesOutput outPut = templates.Execute();
            templatesResults result = outPut.result;

            if (outPut.api_ErrorMessages.Count > 0)
            {
                return false;
            }
            foreach (templatesResults.template template in result.user)
            {
                dicTemplates.Add(template.id, template.name);
            }
            return true;
        }

        public int AddTemplates(string name, string html)
        {
            templateAddInput input = new templateAddInput(_apikey, name, html);
            templateAdd templateAdd = new templateAdd(input);
            templateAddOutput output = templateAdd.Execute();
            return output.result ;
        }

        public string CreateCampaign(string title, string subject, string listId, int templateId)
        {
            var createOptions = new campaignCreateOptions();
            createOptions.title = title;
            createOptions.subject = subject;
            createOptions.from_name = "Pugster";
            createOptions.from_email = "sale@pugsterdeal.com";
            createOptions.list_id = listId;
            createOptions.template_id = templateId;
            createOptions.tracking.opens = true;
            createOptions.tracking.html_clicks = true;
            createOptions.authenticate = true;
            createOptions.auto_tweet = true;

            var segmentOptions = new campaignSegmentOptions();
            var content = new Dictionary<string, string>();
            var typeOpts = new Dictionary<string, string>();

          
            var input = new campaignCreateInput(_apikey, EnumValues.campaign_type.regular, createOptions,
                                                                content, segmentOptions, typeOpts);
            var create = new campaignCreate(input);
            campaignCreateOutput outPut = create.Execute();
           
            return outPut.result;
        }

        public bool SendCampaignNow(string cid)
        {
            var inPut = new campaignSendNowInput(_apikey, cid);
            var send = new campaignSendNow(inPut);
            campaignSendNowOutput outPut = send.Execute();
            return outPut.result;
        }

        public bool SendCampaignSchedule(string cid,DateTime scheduleTime)
        {
            var input = new campaignScheduleInput(_apikey, cid, scheduleTime);
            var schedule = new campaignSchedule(input);
            var output = schedule.Execute();
            return output.result;
        }

        public bool SendCampaignTest(string cid,List<string> emailList)
        {
            var input = new campaignSendTestInput(_apikey, cid, emailList);
            var sendTest = new campaignSendTest(input);
            var output = sendTest.Execute();
            if (output.api_ErrorMessages.Count > 0)
            {
                Trace.WriteLine(output.api_ErrorMessages);
                return false;
            }
            return true;
        }

        public bool GetUnSubscribeEmailFormMailchimp(string listId,DateTime sinceDateTime, out Dictionary<string,DateTime> listUnsubscribedList)
        {
            try
            {
                listUnsubscribedList = new Dictionary<string, DateTime>();
                var input = new listMembersInput(_apikey, listId, EnumValues.listMembers_status.unsubscribed, sinceDateTime);
                var listMembers = new listMembers(input);
                var output = listMembers.Execute();
                foreach (var data in output.result.data)
                {
                    listUnsubscribedList.Add(data.email, data.timestamp);
                }
                return output.api_ErrorMessages.Count == 0;;
            }
            catch (Exception ex)
            {
                listUnsubscribedList = null;
                Trace.WriteLine("GetUnSubscribeEmailFormMailchimp " + ex.ToString());
                return false;
            }
        }
    }

    public class SubscribeEmail
    {
        public string Email;
        public string Fname;
    }
    
}
